// DeviceList.cpp : 实现文件
//implementation file

#include "stdafx.h"
#include "SingleDisplay.h"
#include "DeviceList.h"
#include <map>

using namespace Dahua;

// CDeviceList 对话框
// CDeviceList dialog
IMPLEMENT_DYNAMIC(CDeviceList, CDialog)

CDeviceList::CDeviceList(CWnd* pParent)
	: CDialog(CDeviceList::IDD, pParent)
	, _systemIns(GenICam::CSystem::getInstance())
	, _ipCfgDlg(NULL)
{
}

CDeviceList::~CDeviceList()
{
	if (_ipCfgDlg != NULL)
	{
		delete _ipCfgDlg;
	}
}

void CDeviceList::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

void CDeviceList::initDlg(Proc const& callBack)
{
	assert(callBack);
	
	_cameraVec.clear();
	if (!_systemIns.discovery(_cameraVec))
	{
		MessageBox("Discovery Cameras Failed.", "", 0);
	}
	else
	{
		initTree(_cameraVec);
		_callBackFunc = callBack;
	}
}

void CDeviceList::onSetIpOK()
{
	CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE_DEVLIST);
	pTreeCtrl->SetItemText(_selectItem, _currentCamera->getKey());
}

// 初始化树形结构
// initialize tree structure
void CDeviceList::initTree(CameraVec& cameraPtrVec)
{
	// 获取Interface信息
	// get interface imformation
	struct CameraInfo
	{
		std::string name; // 树形结构的显示信息 | display information of tree structure
		int         idx;  // 该idx为_cameraVec中Camera的序号 | this idx is the serial number of camera in cameravec
	};
	
	typedef std::map< std::string, std::vector<CameraInfo> > InterfaceMap;
	
	// 获取Interface的信息
	// get interface imformation
	InterfaceMap interfaces;
	int idx = 0;
	CameraVec::iterator it = cameraPtrVec.begin();
	for (; it != cameraPtrVec.end(); ++it, ++idx)
	{
		GenICam::ICameraPtr& camPtr = (*it);
		if (camPtr == NULL)
		{
			continue;
		}
		
		std::string intfaceName = camPtr->getInterfaceName();
		InterfaceMap::iterator it = interfaces.find(intfaceName);
		if (it != interfaces.end())
		{
			CameraInfo info = {camPtr->getKey(), idx}; 
			it->second.push_back( info );
		}
		else
		{
			std::vector<CameraInfo> cameraVec;
			CameraInfo info = {camPtr->getKey(), idx}; 
			cameraVec.push_back( info );
			(void)interfaces.insert(std::make_pair(intfaceName, cameraVec));
		}
	}
	
	CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE_DEVLIST);
	assert(NULL != pTreeCtrl);
	
	/// 初始化GUI树形结构
	// initialize GUI tree
	InterfaceMap::iterator iter = interfaces.begin();
	for (; iter != interfaces.end(); ++iter)
	{
		HTREEITEM hInterface = pTreeCtrl->InsertItem(iter->first.c_str(), 0, 0);
		if (hInterface == NULL || iter->second.size() == 0)
		{
			continue;
		}
		pTreeCtrl->SetItemData(hInterface, -1); // -1表示Interface节点 | -1 expression  interface node
		
		std::vector<CameraInfo>::iterator camIter = iter->second.begin();
		for (; camIter != iter->second.end(); ++camIter)
		{
			HTREEITEM item = pTreeCtrl->InsertItem(camIter->name.c_str(), 0, 0, hInterface, TVI_LAST);
			pTreeCtrl->SetItemData(item, camIter->idx); // 相机对象在Vector中的序号 | Camera object's  number in vector
		}
		pTreeCtrl->Expand(hInterface, TVE_EXPAND);
	}
}

BEGIN_MESSAGE_MAP(CDeviceList, CDialog)
	ON_NOTIFY(NM_RCLICK, IDC_TREE_DEVLIST, &CDeviceList::OnNMRclickTreeDevlist)
	ON_COMMAND(ID_MENU_CONNECT, &CDeviceList::OnMenuConnect)
	ON_COMMAND(ID_MENU_MODIFY, &CDeviceList::OnMenuModify)
END_MESSAGE_MAP()

void CDeviceList::OnNMRclickTreeDevlist(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = 0;
	
	CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE_DEVLIST);
	assert(NULL != pTreeCtrl);
	POINT point = GetCurrentMessage()->pt;
	POINT fullScreenPoint = point;
	pTreeCtrl->ScreenToClient(&point);
	
	UINT uFlags = 0;
	HTREEITEM hItem = pTreeCtrl->HitTest(point, &uFlags);
	
	if (NULL == hItem 
		|| !(uFlags & TVHT_ONITEM))
	{
		return;
	}
	
	int idx = (int)pTreeCtrl->GetItemData(hItem);
	if (idx < 0 || idx >= (int)_cameraVec.size())
	{
		return;
	}
	
	CMenu menu;
	menu.LoadMenu(IDR_CAMERA);
	
	GenICam::ICameraPtr& camera = _cameraVec[idx];
	assert(NULL != camera);
	
	// 非GIGE不需要修改IP
	// non GigE camera does not need to modify IP
	if (GenICam::ICamera::typeGige != camera->getType())
	{
		menu.EnableMenuItem(ID_MENU_MODIFY, MF_DISABLED | MF_GRAYED | MF_BYCOMMAND);
	}

	_selectItem = hItem;
	_currentCamera = camera;
	menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, fullScreenPoint.x, fullScreenPoint.y, this);
}

void CDeviceList::OnMenuConnect()
{
	assert(NULL != _currentCamera);
	
	bool ret = false;
	if (!_currentCamera->connect())
	{
		MessageBox("Connect Failed.", "", 0);
	}
	else
	{
		ret = true;
	}
	_callBackFunc(_currentCamera, ret);
	DestroyWindow();
}

void CDeviceList::OnMenuModify()
{
	if (NULL != _ipCfgDlg)
	{
		delete _ipCfgDlg;
	}
	_ipCfgDlg = new IPCfg;
	assert(NULL != _ipCfgDlg);
	_ipCfgDlg->Create(IDD_IP_CFG, this);
	
	_ipCfgDlg->init(_currentCamera, IPCfg::SetIPProc(&CDeviceList::onSetIpOK, this));
	_ipCfgDlg->ShowWindow(SW_SHOW);
}
